package com.ruoyi.web.controller.api;


import com.alibaba.fastjson.JSONObject;
import com.ruoyi.cat.domain.AdTicketClassify2;
import com.ruoyi.cat.domain.AdTicketOrder;
import com.ruoyi.cat.domain.AdTicketRoll;
import com.ruoyi.cat.domain.CatTradedetailTable;
import com.ruoyi.cat.domain.DTO.TicketOrderDTO;
import com.ruoyi.cat.domain.VO.ConfirmRefundVO;
import com.ruoyi.cat.domain.VO.OrderPaymentVO;
import com.ruoyi.cat.domain.VO.RefundVO;
import com.ruoyi.cat.domain.VO.TicketOrderVO;
import com.ruoyi.cat.service.IAdTicketOrderService;
import com.ruoyi.cat.service.IAdTicketRollService;
import com.ruoyi.cat.service.OrderPaymentService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.OrderUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.wxpay.AESUtil;
import com.ruoyi.common.wxpay.WXPayConstants;
import com.ruoyi.common.wxpay.WXPayUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Api(tags = "api-订单详情相关接口")
@RestController
@RequestMapping("/api/oracleTicket")
public class OracleTicketController  extends BaseController {

    @Autowired
    private IAdTicketOrderService adTicketOrderService;

    @Autowired
    private OrderPaymentService orderPaymentService;

    @Autowired
    private IAdTicketRollService iAdTicketRollService;


    @GetMapping("/getTicketData")
    @ApiOperation("订单管理接口")
    public TableDataInfo getTicketData(HttpServletRequest request, TicketOrderVO ticketOrderVO) {
        startPage();
        List<TicketOrderDTO> adGifts = adTicketOrderService.selectAdTicketOrderByOrderCode(ticketOrderVO);
        return getDataTable(adGifts);
    }

    @PostMapping("/confirmRefund")
    @ApiOperation("确认退款接口")
    public AjaxResult confirmRefund(HttpServletRequest request, @RequestBody ConfirmRefundVO confirmRefundVO) {
        AdTicketOrder adTicketOrder = new AdTicketOrder();
        adTicketOrder.setId(confirmRefundVO.getId());
        adTicketOrder.setRefundWay(confirmRefundVO.getRefundWay());
        adTicketOrder.setRefundReason(confirmRefundVO.getRefundReason());
        adTicketOrder.setState("2");
        orderPaymentService.confirmRefundOracle(confirmRefundVO);
        //调用退款接口
        return success( adTicketOrderService.updateAdTicketOrder(adTicketOrder));
    }

    @PostMapping("/payment")
    @ApiOperation("支付相关接口")
    public AjaxResult payment(HttpServletRequest request, @RequestBody OrderPaymentVO orderPaymentVO) {

        return success( orderPaymentService.orderPayment(orderPaymentVO));
    }

    @PostMapping("/wxPayment")
    @ApiOperation("原生微信支付相关接口")
    public AjaxResult wxPayment(HttpServletRequest request, @RequestBody OrderPaymentVO orderPaymentVO) {

        return success( orderPaymentService.wxOrderPayment(orderPaymentVO));
    }

    @PostMapping("/zhifuPayment")
    @ApiOperation("原生支付宝支付相关接口")
    public AjaxResult zhifuPayment(HttpServletRequest request, @RequestBody OrderPaymentVO orderPaymentVO) {

        return success( orderPaymentService.wxOrderPayment(orderPaymentVO));
    }

    @PostMapping("/paymentCallback")
    @ApiOperation("支付回调处理")
    public AjaxResult paymentCallback(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        log.info("------------ 支付回调参数: {}", JSONObject.toJSONString(parameterMap));
        JSONObject response = new JSONObject();
        response.put("resp_code", "200");
        return success(response);
    }

    @PostMapping("/notify")
    public String payCallback(HttpServletRequest res, HttpServletResponse rsp) throws Exception {
        System.out.println("微信支付回调");
        InputStream inStream = res.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        String resultxml = new String(outSteam.toByteArray(), "utf-8");
        logger.error("支付回调接口 {} ",resultxml);
        Map<String, String> params = WXPayUtil.xmlToMap(resultxml);
        logger.error("支付回调接口解析 {} ",params);
        outSteam.close();
        inStream.close();
        //支付结果返回，最后需要返回xml格式的数据
        Map<String, String> return_data = new HashMap<String, String>();
        if (!"SUCCESS".equals(params.get("return_code"))) {
            //没有支付成功
            return_data.put("return_code", "FAIL");
            return_data.put("return_msg", "return_code不正确");
            return WXPayUtil.mapToXml(return_data);
        } else {
            //返回成功了
            //商户订单号
            String outTradeNo = params.get("out_trade_no");
            //订单金额
            String totalFee = params.get("total_fee");
            //支付完成时间
            String timeEnd =params.get("time_end");
            String mch_id =params.get("mch_id");
            //微信支付订单号
            String tradeNo = params.get("transaction_id");
            AdTicketOrder catTradedetailTable = new AdTicketOrder();
            catTradedetailTable.setOrderCode(outTradeNo);
            catTradedetailTable.setState("1");
            catTradedetailTable.setVerificationCode(OrderUtil.generateVerificationCode());
            adTicketOrderService.updateAdTicketOrderByOrderCode(catTradedetailTable);
            //iCatTradedetailTableService.updateCatTradedetailTableOrderNo(catTradedetailTable);
            System.out.println("商户订单号"+outTradeNo+"tradeNo"+tradeNo);
            return_data.put("return_code", "SUCCESS");
            return_data.put("return_msg", "OK");
            return WXPayUtil.mapToXml(return_data);
        }
    }

    @ApiOperation("退款")
    @PostMapping("/refund")
    public AjaxResult refund(HttpServletRequest request, @Validated @RequestBody RefundVO refundVO) {
        //   WxLoginUser wxLoginUser = wxTokenService.getWxUser(request);
        AdTicketOrder hospitalOrder = adTicketOrderService.selectAdTicketOrderById(refundVO.getOrderId());
        // orderVO.setNursingStaffId(orderVO.getNursingStaffId());
        // orderVO.setNursingStaffId(wxLoginUser.getUserId());
        return orderPaymentService.refund(hospitalOrder.getOrderCode(), "", hospitalOrder.getPrice(),hospitalOrder.getPrice());
    }

    /**
     * @Description: 微信退款回调
     * @Author: Mr.Jkx
     * @date: 2020/3/23 16:14
     */
    @RequestMapping(value = "/refundCardOrder")
    public void refundCardOrder(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String xmlStr = "";
        InputStream inStream = request.getInputStream();
        int _buffer_size = 1024;
        if (inStream != null) {
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            byte[] tempBytes = new byte[_buffer_size];
            int count = -1;
            while ((count = inStream.read(tempBytes, 0, _buffer_size)) != -1) {
                outStream.write(tempBytes, 0, count);
            }
            tempBytes = null;
            outStream.flush();
            //将流转换成字符串
            xmlStr = new String(outStream.toByteArray(), "UTF-8");
        }

        Map<String, String> map2 = refundCardMessageDecrypt(xmlStr);
        //	退款状态SUCCESS	SUCCESS-退款成功、CHANGE-退款异常、REFUNDCLOSE—退款关闭
        String refund_status = map2.get("refund_status");
        String transactionId = map2.get("transaction_id");
        String out_refund_no = map2.get("out_refund_no");
        logger.info("退款回调方法 {}",map2);
        logger.info("退款回调方法 {}",transactionId);
        String refundId = map2.get("refund_id");
        AdTicketOrder adTicketOrder = adTicketOrderService.selectAdTicketByRefundOrder(out_refund_no);
        if (WXPayConstants.SUCCESS.equals(refund_status)) {
            // 退款成功支付回调，退款成功，退款逻辑处理 TODO
            //这里需要设置打印
            adTicketOrder.setState("4");

        }else{
            adTicketOrder.setState("5");
            //  hospitalRecord.setErrReason(map2.get("err_code_des"));
        }
        adTicketOrderService.updateAdTicketOrderByOrderCode(adTicketOrder);
        AdTicketRoll adTicketRoll1 = iAdTicketRollService.selectAdTicketRollById(adTicketOrder.getTicketId());
        adTicketRoll1.setQuantity(adTicketOrder.getQuantity()+adTicketRoll1.getQuantity());
        iAdTicketRollService.updateAdTicketRollBy(adTicketRoll1);
        // 微信支付操作成功之后，回执操作
        wxPayReceipt(response);
    }

    /**
     * @Description: 微信退款回调数据解密
     * @Author: Mr.Jkx
     * @date: 2020/6/8 19:04
     */
    public Map<String, String> refundCardMessageDecrypt(String xmlStr) throws Exception {

        Map<String, String> aesMap = new HashMap<>();
        // xml转换为map
        Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
        if (WXPayConstants.SUCCESS.equalsIgnoreCase(map.get("return_code"))) {
            /** 以下字段在return_code为SUCCESS的时候有返回： **/
            // 加密信息：加密信息请用商户秘钥进行解密，详见解密方式
            String req_info = map.get("req_info");
            // 信息解密
            String resultStr = AESUtil.decryptData(req_info);
            aesMap = WXPayUtil.xmlToMap(resultStr);

        } else {
            //LOGGER.info("微信退款-----数据返回失败！！！");
        }
        return aesMap;
    }

    /**
     * @Description: 微信回执信息
     * @Author: Mr.Jkx
     * @date: 2020/5/11 11:19
     */
    private void wxPayReceipt(HttpServletResponse response) throws IOException {
        String resXml = "";
        // 微信支付成功之后，回执操作
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/xml; charset=utf-8");
        PrintWriter out = response.getWriter();
        resXml = "<xml>"
                + "<return_code><![CDATA[SUCCESS]]></return_code>"
                + "<return_msg><![CDATA[OK]]></return_msg>"
                + "</xml> ";
        out.print(resXml);
        out.close();
    }




}
